Skip to content

Conversation

rwhogg
Copy link
Contributor

@rwhogg rwhogg commented Oct 6, 2025

Description

Add support for Firestore Database Clone

Scenarios Tested

  • Clone database without specifying timestamp
  • Clone database with specified timestamp
  • Clone to database that already exists (error)
  • Clone to database with explicit Google-default encryption
  • Clone to database with explicit keep-the-same-encryption config (the default)
  • Clone to database with explicitly chosen KMS key
  • Specify KMS key without explicitly choosing CMEK encryption (error)
  • Specify customer-managed encryption without picking a CMEK key (error)

Sample Commands

  • firebase firestore:databases:clone projects/myproject/databases/original-db projects/myproject/databases/clone (chooses most recent available snapshot)
  • firebase firestore:databases:clone projects/myproject/databases/original-db projects/myproject/databases/clone2 --snapshot-time 2025-10-06T10:00:00Z (uses selected snapshot time)
  • firebase firestore:databases:clone projects/myproject/databases/original-db projects/myproject/databases/db-with-same-encryption --snapshot-time 2025-10-06T10:00:00Z --encryption-type USE_SOURCE_ENCRYPTION
  • firebase firestore:databases:clone projects/myproject/databases/original-db projects/myproject/databases/db-with-kms-encryption --snapshot-time 2025-10-06T10:00:00Z --encryption-type CUSTOMER_MANAGED_ENCRYPTION --kms-key-name projects/myproject/locations/us-central1/keyRings/testkeyring/cryptoKeys/k1
  • firebase firestore:databases:clone projects/myproject/databases/original-db projects/myproject/databases/db-with-google-managed-encryption --snapshot-time 2025-10-06T10:00:00Z --encryption-type GOOGLE_DEFAULT_ENCRYPTION

@rwhogg rwhogg marked this pull request as ready for review October 6, 2025 15:39
@rwhogg rwhogg force-pushed the rh-firestore-clone branch 2 times, most recently from 610c8ed to 224e9f8 Compare October 6, 2025 18:19
@rwhogg rwhogg force-pushed the rh-firestore-clone branch from 224e9f8 to 9bb892b Compare October 7, 2025 13:38
@rwhogg rwhogg requested a review from joehan October 7, 2025 13:39
Copy link
Contributor

@joehan joehan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits and suggestions, but this mostly lgtm

const helpCommandText = "See firebase firestore:databases:clone --help for more info.";

if (options.database) {
throw new FirebaseError(`Please do not use --database for this command. ${helpCommandText}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw new FirebaseError(`Please do not use --database for this command. ${helpCommandText}`);
throw new FirebaseError(`--database is not a supported flag for 'firestoree:databases:clone'. ${helpCommandText}`);

const targetDatabaseId = targetDatabaseName.databaseId;
const sourceProject = parseDatabaseName(sourceDatabase).projectId;
if (parentProject !== sourceProject) {
throw new FirebaseError(`Source and target projects must match.`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw new FirebaseError(`Source and target projects must match.`);
throw new FirebaseError(`Cloning across projects is not supported.`);

"block any incoming third-party traffic.",
);
logger.info();
logger.info(`You can monitor the progress of this clone by executing this command:`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How long is this operation usually? Would it make more sense to just poll on the operation here until it is done?

| UseSourceEncryption
| UseGoogleDefaultEncryption;

export interface PitrSnapshot {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export interface PitrSnapshot {
export interface PITRSnapshot {

payload,
options,
);
const lro = res.body;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to above - we should maybe poll on this using the existing PollOperation utility

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants